package drds.plus.sql_process.type;


import drds.plus.common.model.RowValues;
import drds.plus.common.utils.convertor.Convertor;
import drds.plus.common.utils.convertor.ConvertorHelper;
import drds.plus.sql_process.abstract_syntax_tree.expression.NullValue;
import drds.tools.ShouldNeverHappenException;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 常见类型的转化处理
 */
public abstract class CommonType<Data> extends AbstractType<Data> {

    protected Convertor convertor = null;
    protected Convertor stringConvertor = null;

    public CommonType() {
        convertor = ConvertorHelper.commonToCommon;
        stringConvertor = ConvertorHelper.stringToCommon;
    }

    public ResultGetter getResultGetter() {
        return new ResultGetter() {

            public Object get(ResultSet resultSet, int index) throws SQLException {
                Class clazz = getValueClass();
                if (clazz.equals(Integer.class)) {
                    return resultSet.getInt(index);
                } else if (clazz.equals(Short.class)) {
                    return resultSet.getShort(index);
                } else if (clazz.equals(Long.class)) {
                    return resultSet.getLong(index);
                } else if (clazz.equals(Boolean.class)) {
                    return resultSet.getBoolean(index);
                } else if (clazz.equals(Byte.class)) {
                    return resultSet.getByte(index);
                } else if (clazz.equals(Float.class)) {
                    return resultSet.getFloat(index);
                } else if (clazz.equals(Double.class)) {
                    return resultSet.getDouble(index);
                } else if (clazz.equals(BigInteger.class)) {
                    return resultSet.getBigDecimal(index).toBigInteger();
                } else if (clazz.equals(BigDecimal.class)) {
                    return resultSet.getBigDecimal(index);
                } else {
                    throw new ShouldNeverHappenException(clazz.getSimpleName());
                }
            }

            public Object get(RowValues rowValues, int index) {
                Object object = rowValues.getObject(index);
                return convert(object);
            }

        };
    }

    public int compare(Object o1, Object o2) {
        if (o1 == o2) {
            return 0;
        }
        if (o1 == null) {
            return -1;
        }

        if (o2 == null) {
            return 1;
        }

        Data no1 = convert(o1);
        Data no2 = convert(o2);
        return ((Comparable) no1).compareTo(no2);
    }

    public Data convert(Object value) {
        if (value == null || value instanceof NullValue) {
            return null;
        } else {
            try {
                try {
                    return (Data) convertor.convert(value, getValueClass());
                } catch (RuntimeException e) {
                    Convertor cv = getConvertor(value.getClass());
                    if (cv != null) {
                        return (Data) cv.convert(value, getValueClass());
                    } else {
                        return (Data) value;
                    }
                }
            } catch (NumberFormatException e) {
                // mysql中针对不可识别的字符，返回数字0
                return (Data) stringConvertor.convert("0", getValueClass());
            }
        }
    }

}
